- Let's consider of a function that reads a file. Do we have to wait until the read operation is completed and returns the result?
The code that calls the function will be blocked, and the execution of the program will be blocked for a while.
- Example
function Fibonacci(n) { // It take a long time with n > 40. (Do you know why?)
// Let's assume that this function reads a long file instead of computing a Fibonacci number.
if (n == 0)
return 0;
else if (n == 1)
return 1;
else
return Fibonacci(n-1) + Fibonacci(n-2);
}
function do_io(n) {
let f = Fibonacci(n);
return f;
}
{
let n = 10; // Try with 20, 30, 40, 45, 50
alert('Before');
let result = do_io(n);
alert(result);
alert('After');
}
-
Trial 0.1: Try the above example with different n = 10, 20, 30, 40, 50.
What will happen?
- In the above Trial 0.1, probalbly, the app will not response for a while with n = 50.
Is there any way not to wait the result and to keep moving to the next statements?
Similarly, 'blocking' happens with events, i/o jobs, and data communications.
- Example of timeout
function wait_seconds(n) {
setTimeout(function() { // pass a callback function that is expected to be invoked (i.e., called back) later
alert('wait_seconds: Wake uuuuuuuuuup!');
}, n * 1000);
}
{
let n = 10;
alert('Before');
wait_seconds(n);
alert('After');
}
-
Trial 0.2: Try the above example.
What happens?
- In the above example, the anonymous function passed to setTimeout() is called a callback function.
The code in wait_seconds() is not blocked by setTimeout() and moves to the next statements.
The callback function is invoked (i.e., called back) later from the system.
- Other examples
function perform_io_1() {
// i/o jobs that take some time, for example
setTimeout(function() {
alert('perform_io_1: Done in setTimeout()');
}, 10000);
}
//--------
alert('Before perform_io_1()');
perform_io_1(); // How does this app code know whether perform_io_1() is completed
alert('After perform_io_1()');
//-- anoter example --------------------------------
function perform_io_2(cb) {
// i/o jobs that take some time, for example
setTimeout(function() {
cb('In everything, do to others what you would have them do to you'); // Once the i/o job is comopleted,
// data is passed back through the callback function
}, 10000);
}
//--------
alert('Before perform_io_2()');
perform_io_2(function(???) { // pass a callback function
alert("'" + ??? + "' in perform_io_2()");
});
alert('After perform_io_2()');
-
Trial 0.3: Try the above two examples one by one.
What will happen?
- What are blocking calls and non-blocking calls?
- Blocking calls - waiting till jobs are completed
- A blocking AJAX example
function blockingft() {
let xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() { // callback function from the system
if (this.readyState == 4 && this.status == 200) {
alert("blockingft: Data sent from the server: '" + this.responseText + "'");
}
};
xhttp.open("GET", "test_async.html", false); // Synchronous; AJAX should be completed before going back to the caller.
alert("blockingft: After .open()");
xhttp.send(); // Blocked here, till the data comes back from the server
alert("blockingft: After .send()");
}
- Trial 1: Let's try the above example, with the followings.
Does
blockingft()
go back without waiting the data from the server?
-
blockingft()
waits at .send()
till the data comes from the server.
It is an example of blocking call.
- Non-blocking calls - no-waiting till jobs are completed
- A non-blocking AJAX example
function nonblockingft() {
let xhttp = new XMLHttpRequest();
xhttp.addEventListener('load', function() { // callback function
alert("nonblockingft: Data sent from the server: '" + this.responseText + "'");
});
xhttp.open("GET", "test_async.html", true); // Asynchronous; Go back to the caller before before the data comes from the server.
alert("nonblockingft: After .open()");
xhttp.send();
alert("nonblockingft: After .send()");
}
- Trial 2: Let's try the above example, with the followings.
Does
nonblockingft()
go back without waiting the data from the server?
-
nonblockingft()
does not wait till the data comes from the server.
It is an example of non-blocking call.
- What is asynchronous I/O?
- I/O jobs, such as file, serial, and communication operations, generally take a long time.
Hence it is not a good idea in many cases just to wait till the I/O jobs are completed without doing other jobs.
- Then, how do our programs know whether the I/O jobs are completed? Non-blocking calls with callback functions.
- Trial 3: Let's try the next example.
Can you list messages in the order of displaying?
- What is the event-driven architecture?
- In general I/O jobs, including network I/O, are done by the system.
User applications just use the system I/O API.
- Then, how does the user code know whether an I/O job is completed?
Obviously the answer is to use callback functions.
When a system I/O function, e.g.,
$.get()
in Trial 3, is called, a callback function can be passed.
The callback function is called back when the I/O job is completed.
- How does that work? The answer is the event-driven architecture.
- The event-driven architecture is used not only for I/O jobs, but also for all other events,
like HTML elements related events such as 'click', 'keyup', 'load', and so on.
When I/O jobs are completed, related events are triggered.
- The event-driven programming includes the registration of an event listener for an event on an object,
where the event listener is a callback function that will be called back when the event is triggered on the event.
- Event loop

- What is new in ES6?
let
- block scope variables
const
- constant variables with block scopes; similar to let
except that they cannot be changed
{
const x = 10;
for (let i = 0; i < 20; i++) // Block scope
x += i; // error?
alert(x); // 10 or 30?
alert(window.x); // undefined?
const data = [10, 20];
data.push(30); // error?
alert(data);
}
- A new way to create a property in an object
{
let field_name = "Name";
let document = {};
document[field_name] = "Tom";
// or, a new feature in ES6
document = { [field_name]: "Tom" };
// example
const execute = function(doc) {
alert(JSON.stringify(doc));
}
execute({ [field_name]: "Tom" });
}
- Template Literals
- Read all in JavaScript Template Literals
- What can you do with template literals?
- Quotes inside a string - E.g.,
let msg1 = `Good morning, 'Dave"!`; alert(msg1);
Trial 5.4: Try the above example.
- Multiline strings are supported.
- Expression substitution - E.g.,
let fname = "John"; let lname = "Wayne"; let msg2 = `Good morning, ${fname + ' ' + lname}!`; alert(msg2);
Trial 5.5: Try the above example with two names, "John" and "William".
- Variable sustitution is just an example of expression substitution
- The array methods, map() and forEach(), array destructuring, and array spread operator
- Arrow functions - a bit strange looking syntax
- Read JavaScript Arrow Function.
- Trial 5. Let's try the next example.
- Function hoist is NOT supported for arrow functions. This means that arrow functions should be defined before they are used.
this
in an arrow function refers the object in which the function is defined.
How about this
in a regular function?
- Classes
- Promises for non-blocking operations
- Read JavaScript Promises.
- Syntax -
var p = new Promise(function(resolve, reject) { long-term actions; ... })
,
where resolve
is a callback function used for the normal case, and
reject
is a callback function used for an error case.
p.then(function(...) {...}).catch(function(...) {...})
or
p.then(function(...) {...}, function(...) {...})
- Trial 6: Let's try the next example.
- Does the above example look promising? It does not look more convenient to use.
- Trial 7. Here is an example why Promises look more promising with chaining.
We can avoid multiple nested callbacks using Promises.
- Here is another case for which Promises can be very useful.
Let's assume that there are multiple asynchronous jobs to do.
How can we check if all those jobs are done?
Do we have to keep checking how many jobs are done whenever a job is completed?
- Trial 8. Here is an example.
- Would you like to use Promise?
- Read ES6 - Promises for more features with Promise.
async
and await
, and Promise
- Read JavaScript Async.
async
and await
are extensions of Promise.
async
functions help us write Promise based code as if it were synchronous.
async
functions always return a Promise object.
- The
await
keyword can only be used inside an async
function.
- The
await
keyword makes the function pause the execution and wait for a resolved promise before it continues.
- Trial 9.1 Here is an example.
- Trial 9.2 Which message will be printed first when the button is clicked?
- Trial 9.3 Which message will be printed first when the button is clicked?
Try with "test_async3.html", "test_async3.htmlxxx", and no argument.
- More exercises
- Trial 10.1 Callback version for echo service
- Trial 10.2 Promise version for echo service
- Trial 10.3 Async-await version for echo service - Let's use async-await in the user code.
- Many other new concepts